Java多线程系列---“JUC原子类”05之 AtomicReference原子类

转自:http://www.cnblogs.com/skywang12345/p/3514623.html(部分修改)

概要

本章对AtomicReference引用类型的原子类进行介绍。内容包括:

  • AtomicReference介绍和函数列表
  • AtomicReference源码分析(基于JDK1.7.0_40)
  • AtomicReference示例

AtomicReference介绍和函数列表

AtomicReference是作用是对"对象"进行原子操作。

AtomicReference函数列表

// 使用 null 初始值创建新的 AtomicReference。
AtomicReference()
// 使用给定的初始值创建新的 AtomicReference。
AtomicReference(V initialValue)

// 如果当前值 == 预期值,则以原子方式将该值设置为给定的更新值。
boolean compareAndSet(V expect, V update)
// 获取当前值。
V get()
// 以原子方式设置为给定值,并返回旧值。
V getAndSet(V newValue)
// 最终设置为给定值。
void lazySet(V newValue)
// 设置为给定值。
void set(V newValue)
// 返回当前值的字符串表示形式。
String toString()
// 如果当前值 == 预期值,则以原子方式将该值设置为给定的更新值。
boolean weakCompareAndSet(V expect, V update)

说明
AtomicReference的源码比较简单。它是通过"volatile"和"Unsafe提供的CAS函数实现"原子操作。
(01) value是volatile类型。这保证了:当某线程修改value的值时,其他线程看到的value值都是最新的value值,即修改之后的volatile的值。
(02) 通过CAS设置value。这保证了:当某线程池通过CAS函数(如compareAndSet函数)设置value时,它的操作是原子的,即线程在操作value时不会被中断。

 1 package com.test.a;
 2 
 3 //AtomicReferenceTest.java的源码
 4 import java.util.concurrent.atomic.AtomicReference;
 5 
 6 public class AtomicReferenceTest {
 7 
 8     public static void main(String[] args) {
 9 
10         // 创建两个Person对象,它们的id分别是101和102。
11         Person p1 = new Person(101);
12         Person p2 = new Person(102);
13         // 新建AtomicReference对象,初始化它的值为p1对象
14         AtomicReference ar = new AtomicReference(p1);
15         // 通过CAS设置ar。如果ar的值为p1的话,则将其设置为p2。
16         ar.compareAndSet(p1, p2);
17 
18         Person p3 = (Person) ar.get();
19         System.out.println("p3 is " + p3);
20         System.out.println("p3.equals(p1)=" + p3.equals(p1));
21     }
22 }
23 
24 class Person {
25     volatile long id;
26 
27     public Person(long id) {
28         this.id = id;
29     }
30 
31     public String toString() {
32         return "id:" + id;
33     }
34 }
View Code
1 p3 is id:102
2 p3.equals(p1)=false
View Code

结果说明
新建AtomicReference对象ar时,将它初始化为p1。
紧接着,通过CAS函数对它进行设置。如果ar的值为p1的话,则将其设置为p2。
最后,获取ar对应的对象,并打印结果。p3.equals(p1)的结果为false,这是因为Person并没有覆盖equals()方法,而是采用继承自Object.java的equals()方法;而Object.java中的equals()实际上是调用"=="去比较两个对象,即比较两个对象的地址是否相等。

(note:p2 equasl p3==true)

posted @ 2018-11-04 19:46  Hermioner  阅读(135)  评论(0编辑  收藏  举报